#include "Tank.h"
#include <string.h>
#include <cstdlib>
#include <cmath>
#include <fstream>
#include <list>
using namespace std;
//
/*



 */
#include "core.h"
#include "utils.h"
bool haveEnemyInFeildOFSource(Point sourcePoint) {
	short row = sourcePoint.row;
	short col = sourcePoint.col;
	for (int i = -SOURCE_SIGHT; i <= SOURCE_SIGHT; i++)
		for (int j = -SOURCE_SIGHT; j <= SOURCE_SIGHT; j++)
			if ((abs(i) + abs(j) <= SOURCE_SIGHT)&&(IsOk(row+i,col+j))&& haveEnemy(row + i,
					col + j, gdata))
				return 1;

	return 0;
}
void updateResourceNeedCapture() {
	FlagType myFlag = gdata.myFlag;
	short totalSource = gdata.totalSource;
	short minTank = 0;
	short maxTank = 4;
	if(myFlag==BLUE) {
		minTank=5;
		maxTank=9;
}
	for (int i = 0; i < totalSource; i++) { //
		if (notInDestination(i)
				&& gdata.map[gdata.source[i].row][gdata.source[i].col].isHereSource
						!= myFlag + 1)
			resourceNeedCapture[i] = 1;
		else if ((notInDestination(i))
				&& (gdata.map[gdata.source[i].row][gdata.source[i].col].isHereSource
						== myFlag + 1) && haveEnemyInFeildOFSource(
				gdata.source[i])&&(gdata.map[gdata.source[i].row][gdata.source[i].col].whoIsHere==-1))
			resourceNeedCapture[i] = 1;
		else
			resourceNeedCapture[i] = 0;
	}
}
void updateResourceNeedCapture2() {
	FlagType myFlag = gdata.myFlag;
	short totalSource = gdata.totalSource;
//	short minTank = 0;
//	short maxTank = 4;
//	if(myFlag==BLUE) {
//		minTank=5;
//		maxTank=9;
//}
	for (int i = 0; i < totalSource; i++) { //
		if (gdata.map[gdata.source[i].row][gdata.source[i].col].isHereSource!= myFlag + 1)
			  resourceNeedCapture[i] = 1;
		else
		if ((gdata.map[gdata.source[i].row][gdata.source[i].col].isHereSource== myFlag + 1)
				&& haveEnemyInFeildOFSource(gdata.source[i])) //防御警报矿
			resourceNeedCapture[i] = 1;
		else
			resourceNeedCapture[i] = 0;
	}
}

Order getOrder(short tank_row, short tank_col, short nextStep_row,
		short nextStep_col, DataForAI data) {
	int flag;
	Order order;
	order.type = STOP;
	if (tank_row == nextStep_row && tank_col == nextStep_col) {
		order.type = STOP;
		return order;
	} //
	if (nextStep_row == tank_row - 1)
		flag = 1;
	else if (nextStep_row == tank_row + 1)
		flag = 2;
	else if (nextStep_col == tank_col - 1)
		flag = 3;
	else
		flag = 4;
	CellType cellType = data.map[nextStep_row][nextStep_col].type;
	switch (cellType) {
	case PERVIOUS: {
		if(gdata.tank[gdata.myID].type!=Pioneer) { //非Pioneer坦克，才检测下一步是否有敌人

		if (data.myFlag == RED
				&& data.map[nextStep_row][nextStep_col].whoIsHere > 4) {
			order.type = FIRE;
			order.row = nextStep_row;
			order.col = nextStep_col;
			return order;
		}
		if (data.myFlag == BLUE && (0
				<= data.map[nextStep_row][nextStep_col].whoIsHere
				&& data.map[nextStep_row][nextStep_col].whoIsHere <= 4)) {
			order.type = FIRE;
			order.row = nextStep_row;
			order.col = nextStep_col;
			return order;
		}
}
		if (flag == 1)
			order.type = GOUP;
		else if (flag == 2)
			order.type = GODOWN;
		else if (flag == 3)
			order.type = GOLEFT;
		else if (flag == 4)
			order.type = GORIGHT;
		return order;

	} //
	case BRICK:
		order.type = FIRE;
		order.row = nextStep_row;
		order.col = nextStep_col;
		return order;
	case BREAKBRICK:
		order.type = FIRE;
		order.row = nextStep_row;
		order.col = nextStep_col;
		return order;
	case STONE:
		order.type = STOP;
		return order;
	}
	return order;
}
bool IsNeighbourPoint(Point tank_point, short row, short col){
	bool is=0;
	if(row==tank_point.row-1&&col==tank_point.col) is=1;
	else if(row==tank_point.row&&col==tank_point.col-1) is=1;
	else if(row==tank_point.row+1&&col==tank_point.col) is=1;
	else if(row==tank_point.row&&col==tank_point.col+1) is=1;

	return is;
}
int dealDangeriousCase(Order& order) {
	PathFindingResult pathFindingResult;
	short needExchangeTankNum;
	Point tank_point;
	tank_point.row = gdata.tank[gdata.myID].row;
	tank_point.col = gdata.tank[gdata.myID].col;
	short i;
	for (i=0; i < MAX_TANK_NUM; i++)
		if ((tankHistoryLocationStaticTimes[gdata.myID]== tankHistoryLocationStaticTimes[i] + 1)
				&&(IsNeighbourPoint(tank_point,gdata.tank[i].row,gdata.tank[i].col))) {
			needExchangeTankNum = i;
			break;
		}
	if(i==MAX_TANK_NUM){  //没找到相邻的同方坦克
		pathFindingResult = pathFindingUsingAStar(tank_point,
					gdata.source[destination[gdata.myID] - 1], gdata);
			order = getOrder(tank_point.row, tank_point.col,
					pathFindingResult.nextPoint.row, pathFindingResult.nextPoint.col,
					gdata);
	}
	else {//找到
	short swap = destination[gdata.myID];
	destination[gdata.myID] = destination[needExchangeTankNum];
	destination[needExchangeTankNum] = swap;
	pathFindingResult = pathFindingUsingAStar(tank_point,
			gdata.source[destination[gdata.myID] - 1], gdata);
	order = getOrder(tank_point.row, tank_point.col,
			pathFindingResult.nextPoint.row, pathFindingResult.nextPoint.col,
			gdata);
	}
	return pathFindingResult.takeSourceStep;
}

list<Choice> makeChoiceByFinding(DataForAI& data) {
	list<Choice> ls;
	Choice choice;
	Order order;
	updateResourceNeedCapture();

	//if(gdata.round==56)
	//	fout<<"herer"<<endl;

	//处理同方碰撞
	if (data.tank[data.myID].row == tankHistoryLocation[data.myID].row
			&& data.tank[data.myID].col == tankHistoryLocation[data.myID].col) {
		if(!tankHistoryOderIsFIRE[gdata.myID]&&(!gdata.map[gdata.tank[gdata.myID].row][gdata.tank[gdata.myID].col].isHereSource))
			tankHistoryLocationStaticTimes[data.myID]++;

	} else
		{
		tankHistoryLocationStaticTimes[data.myID] = 0;
		}

	if (tankHistoryLocationStaticTimes[data.myID] > 2) {
		choice.takeSourceStep = dealDangeriousCase(order);
		choice.order = order;
		if(destination[gdata.myID]!=0)
		  choice.destination = destination[gdata.myID]-1;
		ls.push_back(choice);
		return ls;
	}

	tankHistoryLocation[data.myID].row = data.tank[data.myID].row;
	tankHistoryLocation[data.myID].col = data.tank[data.myID].col;

	short tank_row = gdata.tank[gdata.myID].row;
	short tank_col = gdata.tank[gdata.myID].col;
	Point tank_point;
	tank_point.row = tank_row;
	tank_point.col = tank_col;
	//Point nextStep_point;
	PathFindingResult pathFindingResult;
	if ((tank_row == gdata.source[destination[gdata.myID] - 1].row)
			&& (tank_col == gdata.source[destination[gdata.myID] - 1].col)) //鍒拌揪鐙傜偣锛屽氨缃┖鐩爣
		destination[data.myID] = 0;

  if(destination[gdata.myID]){
	short destinationSource_row = gdata.source[destination[gdata.myID]-1].row;
	short destinationSource_col = gdata.source[destination[gdata.myID]-1].col;
    if(gdata.map[destinationSource_row][destinationSource_col].isHereSource==gdata.myFlag+1)
    	destination[data.myID] =0;
}

	int minLength = 65536;
	short minSourceNum = -1;
	for (int i = 0; i < gdata.totalSource; i++) {
		if (resourceNeedCapture[i]) //=1,需要抢占
		{
			int temp = abs(tank_row - gdata.source[i].row) * abs(tank_row
					- gdata.source[i].row)
					+ abs(tank_col - gdata.source[i].col) * abs(tank_col
							- gdata.source[i].col);
			if (temp < minLength) {
				minLength = temp;
				minSourceNum = i;
			}
		}
	} //for

//	if(gdata.round==72&&gdata.myID==3)
//		{fout<<minLength<<" "<<minSourceNum<<endl;
//	      fout<<"destination source num: "<<destination[gdata.myID]-1<<endl;
// 		}

	if (destination[gdata.myID]) //有目标
	{
		short destinationSourceNum = destination[gdata.myID] - 1;
		int length = abs(tank_row - gdata.source[destinationSourceNum].row)
				* abs(tank_row - gdata.source[destinationSourceNum].row) + abs(
				tank_col - gdata.source[destinationSourceNum].col) * abs(
				tank_col - gdata.source[destinationSourceNum].col);
		if (minLength < length) //换目标  ||!resourceNeedCapture[destination[gdata.myID]-1])
		{
			pathFindingResult = pathFindingUsingAStar(tank_point,
					data.source[minSourceNum], gdata);
			order = getOrder(tank_row, tank_col,
					pathFindingResult.nextPoint.row,
					pathFindingResult.nextPoint.col, gdata);
			destination[data.myID] = minSourceNum + 1;
		} else //按照原来的目标走
		{

			pathFindingResult = pathFindingUsingAStar(tank_point,
					data.source[destinationSourceNum], gdata);
			order = getOrder(tank_row, tank_col,
					pathFindingResult.nextPoint.row,
					pathFindingResult.nextPoint.col, gdata);
		}
	} //if
	else //没目标
	{
		if (minSourceNum != -1) {
			pathFindingResult = pathFindingUsingAStar(tank_point,
					data.source[minSourceNum], gdata);
			order = getOrder(tank_row, tank_col,
					pathFindingResult.nextPoint.row,
					pathFindingResult.nextPoint.col, gdata);
			destination[gdata.myID] = minSourceNum + 1;
		} else {
			//没目标，没需要抢占的矿
			// nextStep(order,data,data.totalSource/2);
			//  destination[data.myID]= data.totalSource/2+1;
			if (haveEnemy(tank_row - 1, tank_col, data)) {
				order.type = FIRE;
				order.row = tank_row - 1;
				order.col = tank_col;
			} else if (haveEnemy(tank_row + 1, tank_col, data)) {
				order.type = FIRE;
				order.row = tank_row +1;
				order.col = tank_col;
			} else if (haveEnemy(tank_row, tank_col - 1, data)) {
				order.type = FIRE;
				order.row = tank_row;
				order.col = tank_col - 1;
			} else if (haveEnemy(tank_row, tank_col + 1, data)) {
				order.type = FIRE;
				order.row = tank_row;
				order.col = tank_col + 1;
			} else
				order.type = STOP;
		}
	}

	choice.order = order;
	choice.takeSourceStep = pathFindingResult.takeSourceStep;
	if(destination[gdata.myID]!=0)
	    choice.destination = destination[gdata.myID]-1;
	ls.push_back(choice);
	return ls;
}

struct _MidItem{
	short sourceNum;
	PathFindingResult pathFindingResult;
};
bool compare2(_MidItem t1, _MidItem t2){
	if(t1.pathFindingResult.takeSourceStep<t2.pathFindingResult.takeSourceStep)  return 1;
	else return 0;
}
list<Choice> makeChoiceByFinding2(DataForAI& data){
	list<Choice> ls;
	Choice choice;
	Point tank;
	    tank.row = gdata.tank[gdata.myID].row;
	    tank.col = gdata.tank[gdata.myID].col;
	if(gdata.round==1&&gdata.myID==0)
	{
		for(int i=0;i<gdata.totalSource;i++)
		  {
			NearestTankToSource[i]=0;
			NearestTankToSourceDist[i]=0;
		  }
	}

	if(destination[gdata.myID]) //tank有目标
	{
		 short destination_source_row = gdata.source[destination[gdata.myID]-1].row;
		 short destination_source_col = gdata.source[destination[gdata.myID]-1].col;
		 if(tank.row==destination_source_row&&tank.col==destination_source_col) //坦克到目标
		 {
			NearestTankToSource[destination[gdata.myID]-1]=0;
			destination[gdata.myID]=0;
		  }
	}

	short min=0;
	short max=4;
	if(gdata.myFlag==BLUE) {
		min=5;
		max=9;
	}
	for(int i=min;i<=max;i++)
		if(gdata.tank[i].revive==gdata.round)
			gdata.map[gdata.tank[i].StartRow][gdata.tank[i].StartCol].type=STONE;

	updateResourceNeedCapture2();

	//printResourceNeedCapture();

	list<_MidItem> pathFindingResultList;
    PathFindingResult resultPath;

	for(int i=0;i<gdata.totalSource;i++){
		if(resourceNeedCapture[i]){
			PathFindingResult pathFindingResult = pathFindingUsingAStar2(tank,gdata.source[i]);
		    _MidItem midItem;
		    midItem.sourceNum = i;
		    midItem.pathFindingResult = pathFindingResult;
		    pathFindingResultList.push_back(midItem);
		}
	}
//	for (list<_MidItem>::iterator it = pathFindingResultList.begin(); it
//				!= pathFindingResultList.end(); it++)
//		 fout<<(*it).sourceNum<<" step: "<<(*it).pathFindingResult.takeSourceStep<<"  ";
//	fout<<endl;
	pathFindingResultList.sort(compare2);

//	for (list<_MidItem>::iterator it = pathFindingResultList.begin(); it
//					!= pathFindingResultList.end(); it++)
//			 fout<<(*it).sourceNum<<" step: "<<(*it).pathFindingResult.takeSourceStep<<"  ";
//		fout<<endl;

//   for(int i=0;i<gdata.totalSource;i++)
//	   if(resourceNeedCapture[i])
//	   fout<<i<<" "<<NearestTankToSource[i]<<"     ";
//   fout<<endl;

   list<_MidItem>::iterator it;
	for (it = pathFindingResultList.begin(); it
			!= pathFindingResultList.end(); it++) {
		_MidItem midItem = *it;
		short sourceNum = midItem.sourceNum;
	//	fout<<sourceNum<<"  "<<midItem.pathFindingResult.nextPoint.row<<" "<<midItem.pathFindingResult.nextPoint.col<<endl;
		if (NearestTankToSource[sourceNum]) { // 有坦克驶向该矿
			if (NearestTankToSource[sourceNum] - 1 == gdata.myID) { //矿点的历史最近坦克号和当前坦克的号相同，继续前进
				resultPath = midItem.pathFindingResult;
				break;
			} else { // 不同
				//short oldTankNum = NearestTankToSource[sourceNum] - 1;
				int oldTankToSourceDist = NearestTankToSourceDist[sourceNum];
				if (midItem.pathFindingResult.takeSourceStep < oldTankToSourceDist) {
//					fout<<"NearestTankToSource["<<sourceNum<<"]="<<NearestTankToSource[sourceNum]<<endl;
//					fout<<"NearestTankToSourceDist["<<sourceNum<<"]"<<NearestTankToSourceDist[sourceNum]<<endl;
//					fout<<"midItem.pathFindingResult.tankSourceStep"<<midItem.pathFindingResult.takeSourceStep<<endl;
					destination[NearestTankToSource[sourceNum]-1]=0; // 置空被夺目标矿点的坦克的目标记录
					NearestTankToSource[sourceNum]=gdata.myID+1;
//					fout<<"NearestTankToSource["<<sourceNum<<"]="<<NearestTankToSource[sourceNum]<<endl;
					NearestTankToSourceDist[sourceNum]=midItem.pathFindingResult.takeSourceStep;
					resultPath = midItem.pathFindingResult;
//					fout<<destination[gdata.myID]<<endl;
					if(destination[gdata.myID])
						NearestTankToSource[destination[gdata.myID]-1]=0;  //置空坦克原来的目标矿点的来抢坦克的记录
					destination[gdata.myID]=sourceNum+1;  //修改目标
//					fout<<"NearestTankToSource["<<sourceNum<<"]="<<NearestTankToSource[sourceNum]<<endl;
//
//				    for(int i=0;i<gdata.totalSource;i++)
//				    	   if(resourceNeedCapture[i])
//				    	   fout<<i<<" "<<NearestTankToSource[i]<<"     ";
//				       fout<<endl;

					break;
				} else {
                   //continue; // 继续for循环
				}
			}
		} else { //没有坦克驶向该矿

			NearestTankToSource[sourceNum]=gdata.myID+1;
		    NearestTankToSourceDist[sourceNum]=midItem.pathFindingResult.takeSourceStep;
			resultPath = midItem.pathFindingResult;
			destination[gdata.myID]=sourceNum+1;
			break;
		}


	}
	   if(it==pathFindingResultList.end()) {
		   // 没有目标了 ,驶向中矿
		   resultPath=pathFindingUsingAStar2(tank,gdata.source[gdata.totalSource/2]);
		   choice.order = getOrder(tank.row,tank.col,resultPath.nextPoint.row,resultPath.nextPoint.col,gdata);
		   choice.takeSourceStep = resultPath.takeSourceStep;
		   ls.push_back(choice);
	   return ls;
	   }


		choice.order = getOrder(tank.row,tank.col,resultPath.nextPoint.row,resultPath.nextPoint.col,gdata);
		choice.takeSourceStep = resultPath.takeSourceStep;

		ls.push_back(choice);


		return ls;

}



list<Choice> makeChoiceByDefend(DataForAI& data) {
	list<Choice> ls;
	return ls;
}
